﻿using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using KPIS.GERP.Models;
using KPIS.GERP.Models.Class;
using KPIS.GERP.Models.HRM;
using KPIS.GERP.Models.SYS;
using System.Data.Entity;
using KPIS.GERP.Models.SYS.ViewModel;
using System;

namespace KPIS.GERP.WCF.SYS
{
    [ServiceContract]
    public interface IUserService
    {
        [OperationContract]
        Position GetPositionByUser(int userId);

        [OperationContract]
        Employee GetEmployeeByUser(int userId);

        [OperationContract]
        User GetUser(int userId);

        [OperationContract]
        User GetUserByUserCode(string userCode);

        [OperationContract]
        User GetUserByEmployee(int empId);

        [OperationContract]
        User GetUserByPosition(int posId);

        [OperationContract]
        IEnumerable<User> GetUsers();

        [OperationContract]
        string GetUsernameByUserId(int userId);

        [OperationContract]
        KPIS.GERP.Models.SYS.ViewModel.UserProfile[] GetUserProfile();

        [OperationContract]
        Employee GetNameApproveTask(string Code);
    }

    [ServiceErrorBehavior(typeof (ElmahErrorHandler))]
    [System.ServiceModel.Activation.AspNetCompatibilityRequirements(
     RequirementsMode = System.ServiceModel.Activation.AspNetCompatibilityRequirementsMode.Allowed)]
    public class UserService : IUserService
    {
        #region Implementation of IUserService

        public Position GetPositionByUser(int userId)
        {
            using (var db = new GERPContext(false))
            {
                return (from u in db.Users.Include(o => o.Employee.Position) where u.UserId == userId select u.Employee.Position).FirstOrDefault();
            }
        }

        public Employee GetEmployeeByUser(int userId)
        {
            Employee employee = null;
            using (var db = new GERPContext(false))
            {
                var position = (from u in db.Users.Include(o => o.Employee.Position) where u.UserId == userId select u.Employee.Position).FirstOrDefault();
                if (position != null)
                {
                    employee = (from e in db.Employees where e.PosId == position.PosId select e).FirstOrDefault();
                }
            }
            return employee;
        }

        public User GetUser(int userId)
        {
            using (var db = new GERPContext(false))
            {
                var user = (from u in db.Users.Include(o => o.Employee.Position)
                                .Include(o => o.Employee.JobSite)
                                .Include(o => o.Employee.MasReligion)
                                .Include(o => o.Employee.MasEmployeeType)
                                .Include(o => o.Employee.MasClass)
                                .Include(o => o.Employee.MasMaritalStatus)
                                .Include(o => o.Employee.MasNamePrefix)
                                .Include(o => o.Employee.ExecutivePosition)
                            select u).ToList();
                var us = user.FirstOrDefault(o => o.UserId == userId);
                return us;
            }
        }

        public User GetUserByUserCode(string userCode)
        {
            using (var db = new GERPContext(false))
            {
                var queryWithPosition = db.Users.Include(o => o.Employee.Position);
                var  query = (from u in queryWithPosition
                        where u.Code == userCode &&
                              u.RecordStatus != RecordStatus.DeletedStatus
                        select u).FirstOrDefault();

                return query;
            }
        }

        public User GetUserByEmployee(int empId)
        {
            using (var db = new GERPContext(false))
            {
                return (from u in db.Users.Include(o=>o.Employee)
                        where u.Employee != null &&
                              u.Employee.EmpId == empId &&
                              u.RecordStatus != RecordStatus.DeletedStatus &&
                              u.Employee.RecordStatus != RecordStatus.DeletedStatus
                        select u).FirstOrDefault();
            }
        }

        public User GetUserByPosition(int posId)
        {
            using (var db = new GERPContext(false))
            {
                return (from u in db.Users
                        where u.Employee != null &&
                              u.Employee.PosId == posId &&
                              u.RecordStatus != RecordStatus.DeletedStatus &&
                              u.Employee.RecordStatus != RecordStatus.DeletedStatus
                        select u).FirstOrDefault();
            }
        }

        public IEnumerable<User> GetUsers()
        {
            using (var db = new GERPContext(false))
            {
                try
                {
                    var models = (from u in db.Users.Include(o => o.Employee.Position).Include(o => o.Employee.JobSite).Include(o => o.Employee.MasNamePrefix)
                                  where u.RecordStatus != RecordStatus.DeletedStatus
                                  select u).ToList(); 
                    return models;
                }
                catch (Exception ex1)
                {
                    try
                    {
                        return (from u in db.Users.Include(o => o.Employee.Position)
                                where u.RecordStatus != RecordStatus.DeletedStatus
                                select u).ToList();

                        throw ex1;
                    }
                    catch (Exception ex2)
                    {
                        try
                        {
                            return (from u in db.Users.Include(o => o.Employee.JobSite)
                                    where u.RecordStatus != RecordStatus.DeletedStatus
                                    select u).ToList();

                            throw ex2;
                        }
                        catch (Exception ex3)
                        {
                            
                            return (from u in db.Users
                                    where u.RecordStatus != RecordStatus.DeletedStatus
                                    select u).ToList();

                            throw ex3;
                        }
                    }
                }
            }
        }

        public string GetUsernameByUserId(int userId)
        {
            using (var db = new GERPContext(false))
            {
                return (from u in db.Users 
                        where u.UserId == userId && 
                        u.RecordStatus != RecordStatus.DeletedStatus 
                        select u.Code).FirstOrDefault();
            }
        }

        public UserProfile[] GetUserProfile()
        {
            using (var db = new GERPContext(false))
            {
                var upf = db.Database.SqlQuery<UserProfile>("select UserId, UserName from UserProfile");
                return upf.ToArray();
            }
        }

        public Employee GetNameApproveTask(string Code)
        {
            using (var db = new GERPContext(false))
            {
                var task = db.Tasks.Include(o=>o.Simulates).FirstOrDefault(o => o.RefCode == Code && o.RecordStatus != "D");
                if (task == null) return null;
                 
                if (task.Completed && task.ApprovedBy.HasValue)
                {
                    var x = (from u in db.Tasks
                             // join a in db.TaskHistories on u.CurrentTaskHistoryId equals a.TaskHistoryId
                             join b in db.Employees.Include(o => o.Position) on u.ApprovedBy equals b.EmpId
                             where u.RefCode == Code &&
                                   u.RecordStatus != RecordStatus.DeletedStatus
                             select b).FirstOrDefault();
                    return x;

                }
               /*  if (task.Completed && task.ApprovedBy.HasValue)
                {
                    var x = (from u in db.Tasks
                             join a in db.TaskHistories on u.CurrentTaskHistoryId equals a.TaskHistoryId
                             join b in db.Employees.Include(o => o.Position) on a.ApproverPosId equals b.EmpId
                             where u.RefCode == Code &&
                                   u.RecordStatus != RecordStatus.DeletedStatus
                             select b).FirstOrDefault();
                    return x;

                }*/
                else if (!task.Completed)
                {
                    var posId = task.Simulates.Last(o => o.IsApproveAble).ApproverPosId;

                    return db.Employees.Include(o => o.Position).First(o => o.PosId == posId); 
                }
                else
                {
                    var x = (from u in db.Tasks
                             join b in db.Employees.Include(o => o.Position) on u.ApprovedBy equals b.EmpId
                             where u.RefCode == Code &&
                                   u.RecordStatus != RecordStatus.DeletedStatus
                             select b).FirstOrDefault();
                    return x;

                }
            }
        }

        #endregion
    }
}